define(['jquery'], ($) => {
  class Zoom {
    constructor (imgBox, imgBigBox) {
      this.$imgBox = $(imgBox)
      this.$imgBigBox = $(imgBigBox)
      this.$img = $(imgBox).find('img')
      this.$imgBig = $(imgBigBox).find('img')
      this.bindEvent()
    }

    createZoomLen () {
      const img = this.$img

      // 创建并插入放大镜
      this.$span = $('<span>').css({
        width: img.width() / this.M * this.N,
        height: img.height() / this.M * this.N,
        background: '#fff',
        position: 'absolute',
        top: 0,
        left: 0,
        zIndex: 2,
        opacity: 0.4,
        cursor: 'move',
        border: '1px solid #aaa'
      }).appendTo(this.$imgBox)
    }

    calcM () {
      // 计算放大比例
      this.M = this.$imgBig.width() / this.$img.width()
      this.N = this.$imgBigBox.width() / this.$imgBox.width()
    }

    bindEvent () {
      this.$imgBox
        .on('mouseenter', () => {
          this.$imgBigBox.show()
          this.calcM()
          this.createZoomLen()
        })
        .on('mouseleave', () => {
          this.$span.remove()
          this.$imgBigBox.hide()
        })
        .on('mousemove', (e) => {
          // 计算鼠标到图片盒子的距离
          const boxLeft = e.pageX - this.$imgBox.offset().left
          const boxTop = e.pageY - this.$imgBox.offset().top

          // 计算放大镜的左上角坐标
          const left = boxLeft - this.$span.width() / 2
          const top = boxTop - this.$span.height() / 2

          this.moveZoomLen(left, top)
        })
    }

    moveZoomLen (left, top) {
      // 计算边界
      const maxLeft = this.$imgBox.width() - this.$span.width() - 1
      const maxTop = this.$imgBox.height() - this.$span.height() - 1

      // 判断边界
      if (left < 0) left = 0
      else if (left > maxLeft) left = maxLeft
      if (top < 0) top = 0
      else if (top > maxTop) top = maxTop

      this.$span.css('left', left)
      this.$span.css('top', top)
      this.$imgBig.css('left', -this.M * left)
      this.$imgBig.css('top', -this.M * top)
    }
  }

  return Zoom
})
